package main

import (
	"fmt"
	"time"

	modbus "gitee.com/barryzxy/gomodbus"
)

func testDataRecord() {
	fmt.Println("\n1. 数据记录结构测试:")

	// 创建数据记录
	record := &modbus.DataRecord{
		Pressure:         25.8,
		PressureUnit:     modbus.PressureUnitKPa,
		BatteryLevel:     88,
		ConnectionStatus: 1,
		SignalLevel:      4,
		Timestamp:        uint32(time.Now().Unix()),
	}

	fmt.Printf("   原始记录: 压力=%.1f %s, 电量=%d%%, 连接=%s, 信号=%s\n",
		record.Pressure,
		modbus.GetPressureUnitName(record.PressureUnit),
		record.BatteryLevel,
		modbus.GetConnectionStatusName(record.ConnectionStatus),
		record.GetSignalStrengthDescription())

	// 转换为字节数组
	bytes := record.ToBytes()
	fmt.Printf("   字节数组 (16字节): %x\n", bytes)

	// 从字节数组还原
	restored, err := modbus.NewDataRecordFromBytes(bytes)
	if err != nil {
		fmt.Printf("   错误: %v\n", err)
		return
	}

	fmt.Printf("   还原记录: 压力=%.1f %s, 电量=%d%%, 连接=%s, 信号=%s\n",
		restored.Pressure,
		modbus.GetPressureUnitName(restored.PressureUnit),
		restored.BatteryLevel,
		modbus.GetConnectionStatusName(restored.ConnectionStatus),
		restored.GetSignalStrengthDescription())

	// 验证数据一致性
	if record.Pressure == restored.Pressure &&
		record.PressureUnit == restored.PressureUnit &&
		record.BatteryLevel == restored.BatteryLevel &&
		record.ConnectionStatus == restored.ConnectionStatus &&
		record.SignalLevel == restored.SignalLevel &&
		record.Timestamp == restored.Timestamp {
		fmt.Printf("   ✓ 数据转换测试通过\n")
	} else {
		fmt.Printf("   ✗ 数据转换测试失败\n")
	}
}

func testPressureUnits() {
	fmt.Println("\n2. 压力单位测试:")

	units := []struct {
		value uint8
		name  string
	}{
		{modbus.PressureUnitMbar, "mbar"},
		{modbus.PressureUnitBar, "bar"},
		{modbus.PressureUnitPsi, "psi"},
		{modbus.PressureUnitPa, "Pa"},
		{modbus.PressureUnitKPa, "kPa"},
		{modbus.PressureUnitMPa, "MPa"},
		{modbus.PressureUnitMmH2O, "mmH₂O"},
		{modbus.PressureUnitMH2O, "mH₂O"},
		{modbus.PressureUnitFtH2O, "ftH₂O"},
		{modbus.PressureUnitInH2O, "inH₂O"},
	}

	for _, unit := range units {
		actualName := modbus.GetPressureUnitName(unit.value)
		if actualName == unit.name {
			fmt.Printf("   ✓ 单位 0x%02X = %s\n", unit.value, actualName)
		} else {
			fmt.Printf("   ✗ 单位 0x%02X 期望 %s, 实际 %s\n", unit.value, unit.name, actualName)
		}
	}
}

func testParameterConstants() {
	fmt.Println("\n3. 参数地址常量测试:")

	fmt.Println("   变送器参数地址:")
	subDevParams := []struct {
		addr uint16
		name string
	}{
		{modbus.SubDevParamPressureUnit, "压力单位"},
		{modbus.SubDevParamLCDDecimalPlaces, "液晶显示小数位"},
		{modbus.SubDevParamTransmitterAddr, "变送器地址"},
		{modbus.SubDevParamLanguage, "语言"},
		{modbus.SubDevParamLCDRotation, "液晶旋转"},
		{modbus.SubDevParamLCDDisplayStatus, "液晶显示状态"},
		{modbus.SubDevParamBacklightTime, "背光显示时间"},
		{modbus.SubDevParamLCDPassword, "液晶操作密码"},
		{modbus.SubDevParamDataReportInterval, "数据上报间隔"},
		{modbus.SubDevParamZeroReset, "零点清零"},
	}

	for _, param := range subDevParams {
		fmt.Printf("   - %s: 0x%04X\n", param.name, param.addr)
	}

	fmt.Println("   网关参数地址:")
	gatewayParams := []struct {
		addr uint16
		name string
	}{
		{modbus.GatewayParamTime, "时间"},
		{modbus.GatewayParamRS485Baudrate, "RS485波特率"},
		{modbus.GatewayParamRS485Address, "RS485地址"},
		{modbus.GatewayParamBacklightTime, "背光显示时间"},
	}

	for _, param := range gatewayParams {
		fmt.Printf("   - %s: 0x%04X\n", param.name, param.addr)
	}

	fmt.Println("   功能码:")
	funcCodes := []struct {
		code uint8
		name string
	}{
		{modbus.FuncCodeGatewayReadDataRecords, "读数据记录"},
		{modbus.FuncCodeGatewayReadCurrentData, "读当前数据"},
		{modbus.FuncCodeGatewayWriteSubDevParam, "写子设备参数"},
		{modbus.FuncCodeGatewayWriteGWParam, "写网关参数"},
	}

	for _, fc := range funcCodes {
		fmt.Printf("   - %s: 0x%02X\n", fc.name, fc.code)
	}

	fmt.Println("   异常码:")
	exceptions := []struct {
		code uint8
		name string
	}{
		{modbus.ExceptionCodeGatewayReadDataError, "读数据异常"},
		{modbus.ExceptionCodeGatewayReadDataError2, "读数据异常（备用）"},
		{modbus.ExceptionCodeGatewayWriteSubDevError, "写子设备参数异常"},
		{modbus.ExceptionCodeGatewayWriteGWError, "写网关参数异常"},
	}

	for _, ex := range exceptions {
		fmt.Printf("   - %s: 0x%02X\n", ex.name, ex.code)
	}
}

func main() {
	fmt.Println("=== 网关协议客户端数据结构测试 ===")

	// 1. 测试数据记录创建和转换
	testDataRecord()

	// 2. 测试压力单位
	testPressureUnits()

	// 3. 测试参数地址常量
	testParameterConstants()

	fmt.Println("\n=== 测试完成 ===")
}
